﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DnPakExplorer {
	/// <summary>
	/// 装备面板类，此类管理角色所装备的物品（武器，纹章，饰品等具有属性加成的物品）以及应用效果
	/// </summary>
	public class EquipmentPanel{
		/// <summary>
		/// 装备的所有物品
		/// </summary>
		private Dictionary<int, IEquipmentProperyable> mItemSlot;
		/// <summary>
		/// 应用的所有套装效果
		/// </summary>
		private Dictionary<int, SetEntry> mEquipedSets = new Dictionary<int, SetEntry>();
		/// <summary>
		/// 套装一装备的套装物品的数量
		/// </summary>
		private Dictionary<int, int> mSetCounts = new Dictionary<int, int>();

		/// <summary>
		/// 属性统计加和
		/// </summary>
		private float[] mFloatProperty = new float[(int)PropertyID.ID_MAX];

		#region 物品槽类型常量

		public const int IS_MAIN_WEAPON				= 0;
		public const int IS_SECONDARY_WEAPON		= 1;
		public const int IS_HEAD					= 2;
		public const int IS_BODY					= 3;
		public const int IS_LEG						= 4;
		public const int IS_HAND					= 5;
		public const int IS_BOOTS					= 6;
		public const int IS_NECKLACE				= 7;
		public const int IS_EARRING					= 8;
		public const int IS_RING1					= 9;
		public const int IS_RING2					= 10;
		public const int IS_SOURCE					= 11;

		public const int IS_CASH_MAIN_WEAPON		= 12;
		public const int IS_CASH_SECONDARY_WEAPON	= 13;
		public const int IS_CASH_HEAD				= 14;
		public const int IS_CASH_BODY				= 15;
		public const int IS_CASH_LEG				= 16;
		public const int IS_CASH_HAND				= 17;
		public const int IS_CASH_BOOTS				= 18;
		public const int IS_CASH_NECKLACE			= 19;
		public const int IS_CASH_EARRING			= 20;
		public const int IS_CASH_RING1				= 21;
		public const int IS_CASH_RING2				= 22;
		public const int IS_CASH_WING				= 23;
		
		public const int IS_CASH_STAMP				= 24;
		public const int IS_CASH_FAIRY				= 25;

		public const int IS_PET						= 26;
		public const int IS_PET_CLOTH1				= 27;
		public const int IS_PET_CLOTH2				= 28;
		public const int IS_RIDE					= 29;

		public const int IS_GLYGH_NORMAL1			= 30;
		public const int IS_GLYGH_NORMAL2			= 31;
		public const int IS_GLYGH_NORMAL3			= 32;
		public const int IS_GLYGH_NORMAL4			= 33;
		public const int IS_GLYGH_NORMAL5			= 34;
		public const int IS_GLYGH_NORMAL6			= 35;
		public const int IS_GLYGH_NORMAL7			= 36;
		public const int IS_GLYGH_NORMAL8			= 37;

		public const int IS_GLYGH_S1				= 38;
		public const int IS_GLYGH_S2				= 39;
		public const int IS_GLYGH_S3				= 40;
		public const int IS_GLYGH_S4				= 41;

		public const int IS_TALISMAN_2001			= 42;
		public const int IS_TALISMAN_2002			= 43;
		public const int IS_TALISMAN_1751			= 44;
		public const int IS_TALISMAN_1752			= 45;
		public const int IS_TALISMAN_1251			= 48;
		public const int IS_TALISMAN_1252			= 49;
		public const int IS_TALISMAN_1001			= 50;
		public const int IS_TALISMAN_1002			= 51;

		public const int IS_CASH_TALISMAN_200		= 52;
		public const int IS_CASH_TALISMAN_175		= 53;
		public const int IS_CASH_TALISMAN_125		= 55;
		public const int IS_CASH_TALISMAN_100		= 56;

		public const int IS_CASH_GLYGH1				= 57;
		public const int IS_CASH_GLYGH2				= 58;
		public const int IS_CASH_GLYGH3				= 59;
		public const int IS_CASH_TAIL				= 60;

		public const int IS_GLYGH_SKILL1			= 61;
		public const int IS_GLYGH_SKILL2			= 62;
		public const int IS_GLYGH_SKILL3			= 63;
		public const int IS_GLYGH_SKILL4			= 64;

		public const int IS_MAX_COUNT				= 65;

		#endregion

		/// <summary>
		/// 物品槽能装备的物品类型
		/// </summary>
		private static ItemType[] mItemSlotType;
		/// <summary>
		/// 物品槽类型
		/// </summary>
		private static string[] mItemSlotName;
		/// <summary>
		/// 所属的角色
		/// </summary>
		private Character mCharacter;

		/// <summary>
		/// 获取所有物品槽
		/// </summary>
		public Dictionary<int, IEquipmentProperyable>.ValueCollection ItemSlots {
			get {
				return mItemSlot.Values;
			}
		}

		/// <summary>
		/// 所属角色
		/// </summary>
		public Character Character {
			get { return mCharacter; }
		}

		static EquipmentPanel() {
			mItemSlotType = new ItemType[EquipmentPanel.IS_MAX_COUNT];
			mItemSlotType[EquipmentPanel.IS_MAIN_WEAPON] = ItemType.Weapon1;
			mItemSlotType[EquipmentPanel.IS_SECONDARY_WEAPON] = ItemType.Weapon2;
			mItemSlotType[EquipmentPanel.IS_HEAD] = ItemType.Head;
			mItemSlotType[EquipmentPanel.IS_BODY] = ItemType.Body;
			mItemSlotType[EquipmentPanel.IS_LEG] = ItemType.Leg;
			mItemSlotType[EquipmentPanel.IS_HAND] = ItemType.Head;
			mItemSlotType[EquipmentPanel.IS_BOOTS] = ItemType.Boots;
			mItemSlotType[EquipmentPanel.IS_NECKLACE] = ItemType.Necklace;
			mItemSlotType[EquipmentPanel.IS_EARRING] = ItemType.Earing;
			mItemSlotType[EquipmentPanel.IS_RING1] = ItemType.Ring;
			mItemSlotType[EquipmentPanel.IS_RING2] = ItemType.Ring;
			mItemSlotType[EquipmentPanel.IS_SOURCE] = ItemType.Source;

			mItemSlotType[EquipmentPanel.IS_CASH_MAIN_WEAPON] = ItemType.Weapon1Cash;
			mItemSlotType[EquipmentPanel.IS_CASH_SECONDARY_WEAPON] = ItemType.Weapon2Cash;
			mItemSlotType[EquipmentPanel.IS_CASH_HEAD] = ItemType.HeadCash;
			mItemSlotType[EquipmentPanel.IS_CASH_BODY] = ItemType.BodyCash;
			mItemSlotType[EquipmentPanel.IS_CASH_LEG] = ItemType.LegCash;
			mItemSlotType[EquipmentPanel.IS_CASH_HAND] = ItemType.HeadCash;
			mItemSlotType[EquipmentPanel.IS_CASH_BOOTS] = ItemType.BootsCash;
			mItemSlotType[EquipmentPanel.IS_CASH_NECKLACE] = ItemType.NecklaceCash;
			mItemSlotType[EquipmentPanel.IS_CASH_EARRING] = ItemType.EaringCash;
			mItemSlotType[EquipmentPanel.IS_CASH_RING1] = ItemType.RingCash;
			mItemSlotType[EquipmentPanel.IS_CASH_RING2] = ItemType.RingCash;
			mItemSlotType[EquipmentPanel.IS_CASH_WING] = ItemType.WingCash;
			mItemSlotType[EquipmentPanel.IS_CASH_TAIL] = ItemType.TailCash;
			mItemSlotType[EquipmentPanel.IS_CASH_STAMP] = ItemType.StampCash;
			mItemSlotType[EquipmentPanel.IS_CASH_FAIRY] = ItemType.FairyCash;

			mItemSlotType[EquipmentPanel.IS_PET						] = ItemType.Vehicle;
			mItemSlotType[EquipmentPanel.IS_PET_CLOTH1				] = ItemType.Vehicle;
			mItemSlotType[EquipmentPanel.IS_PET_CLOTH2				] = ItemType.Vehicle;
			mItemSlotType[EquipmentPanel.IS_RIDE					] = ItemType.Vehicle;

			mItemSlotType[EquipmentPanel.IS_GLYGH_NORMAL1			] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_NORMAL2			] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_NORMAL3			] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_NORMAL4			] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_NORMAL5			] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_NORMAL6			] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_NORMAL7			] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_NORMAL8			] = ItemType.Glyph;

			mItemSlotType[EquipmentPanel.IS_GLYGH_S1] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_S2] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_S3] = ItemType.Glyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_S4] = ItemType.Glyph;

			mItemSlotType[EquipmentPanel.IS_GLYGH_SKILL1] = ItemType.SkillGlyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_SKILL2] = ItemType.SkillGlyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_SKILL3] = ItemType.SkillGlyph;
			mItemSlotType[EquipmentPanel.IS_GLYGH_SKILL4] = ItemType.SkillGlyph;

			mItemSlotType[EquipmentPanel.IS_TALISMAN_2001] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_TALISMAN_2002] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_TALISMAN_1751] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_TALISMAN_1752] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_TALISMAN_1251] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_TALISMAN_1252] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_TALISMAN_1001] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_TALISMAN_1002] = ItemType.Tailsman;

			mItemSlotType[EquipmentPanel.IS_CASH_TALISMAN_200] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_CASH_TALISMAN_175] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_CASH_TALISMAN_125] = ItemType.Tailsman;
			mItemSlotType[EquipmentPanel.IS_CASH_TALISMAN_100] = ItemType.Tailsman;

			mItemSlotType[EquipmentPanel.IS_CASH_GLYGH1] = 0;
			mItemSlotType[EquipmentPanel.IS_CASH_GLYGH2] = 0;
			mItemSlotType[EquipmentPanel.IS_CASH_GLYGH3] = 0;


			mItemSlotName = new string[EquipmentPanel.IS_MAX_COUNT];
			mItemSlotName[EquipmentPanel.IS_MAIN_WEAPON] = "主武器";
			mItemSlotName[EquipmentPanel.IS_SECONDARY_WEAPON] = "副武器";
			mItemSlotName[EquipmentPanel.IS_HEAD] = "帽子";
			mItemSlotName[EquipmentPanel.IS_BODY] = "上装";
			mItemSlotName[EquipmentPanel.IS_LEG] = "下装";
			mItemSlotName[EquipmentPanel.IS_HAND] = "手套";
			mItemSlotName[EquipmentPanel.IS_BOOTS] = "鞋子";
			mItemSlotName[EquipmentPanel.IS_NECKLACE] = "项链";
			mItemSlotName[EquipmentPanel.IS_EARRING] = "耳环";
			mItemSlotName[EquipmentPanel.IS_RING1] = "戒指1";
			mItemSlotName[EquipmentPanel.IS_RING2] = "戒指2";
			mItemSlotName[EquipmentPanel.IS_SOURCE] = "根源";

			mItemSlotName[EquipmentPanel.IS_CASH_MAIN_WEAPON] = "时装主武器";
			mItemSlotName[EquipmentPanel.IS_CASH_SECONDARY_WEAPON] = "时装副武器";
			mItemSlotName[EquipmentPanel.IS_CASH_HEAD] = "时装帽子";
			mItemSlotName[EquipmentPanel.IS_CASH_BODY] = "时装上衣";
			mItemSlotName[EquipmentPanel.IS_CASH_LEG] = "时装裤子";
			mItemSlotName[EquipmentPanel.IS_CASH_HAND] = "时装手套";
			mItemSlotName[EquipmentPanel.IS_CASH_BOOTS] = "时装鞋子";
			mItemSlotName[EquipmentPanel.IS_CASH_NECKLACE] = "时装项链";
			mItemSlotName[EquipmentPanel.IS_CASH_EARRING] = "时装耳环";
			mItemSlotName[EquipmentPanel.IS_CASH_RING1] = "时装戒指1";
			mItemSlotName[EquipmentPanel.IS_CASH_RING2] = "时装戒指2";
			mItemSlotName[EquipmentPanel.IS_CASH_WING] = "翅膀";
			mItemSlotName[EquipmentPanel.IS_CASH_TAIL] = "尾巴";
			mItemSlotName[EquipmentPanel.IS_CASH_STAMP] = "印花";
			mItemSlotName[EquipmentPanel.IS_CASH_FAIRY] = "精灵";

			mItemSlotName[EquipmentPanel.IS_PET] = "宠物";
			mItemSlotName[EquipmentPanel.IS_PET_CLOTH1] = "宠物服装1";
			mItemSlotName[EquipmentPanel.IS_PET_CLOTH2] = "宠物服装2";
			mItemSlotName[EquipmentPanel.IS_RIDE] = "坐骑";

			mItemSlotName[EquipmentPanel.IS_GLYGH_NORMAL1] = "普通纹章1";
			mItemSlotName[EquipmentPanel.IS_GLYGH_NORMAL2] = "普通纹章2";
			mItemSlotName[EquipmentPanel.IS_GLYGH_NORMAL3] = "普通纹章3";
			mItemSlotName[EquipmentPanel.IS_GLYGH_NORMAL4] = "普通纹章4";
			mItemSlotName[EquipmentPanel.IS_GLYGH_NORMAL5] = "普通纹章5";
			mItemSlotName[EquipmentPanel.IS_GLYGH_NORMAL6] = "普通纹章6";
			mItemSlotName[EquipmentPanel.IS_GLYGH_NORMAL7] = "普通纹章7";
			mItemSlotName[EquipmentPanel.IS_GLYGH_NORMAL8] = "普通纹章8";

			mItemSlotName[EquipmentPanel.IS_GLYGH_S1] = "远征纹章1";
			mItemSlotName[EquipmentPanel.IS_GLYGH_S2] = "远征纹章2";
			mItemSlotName[EquipmentPanel.IS_GLYGH_S3] = "远征纹章3";
			mItemSlotName[EquipmentPanel.IS_GLYGH_S4] = "远征纹章4";

			mItemSlotName[EquipmentPanel.IS_GLYGH_SKILL1] = "技能纹章1";
			mItemSlotName[EquipmentPanel.IS_GLYGH_SKILL2] = "技能纹章2";
			mItemSlotName[EquipmentPanel.IS_GLYGH_SKILL3] = "技能纹章3";
			mItemSlotName[EquipmentPanel.IS_GLYGH_SKILL4] = "技能纹章4";

			mItemSlotName[EquipmentPanel.IS_TALISMAN_2001] = "普通护符1(200%)";
			mItemSlotName[EquipmentPanel.IS_TALISMAN_2002] = "普通护符2(200%)";
			mItemSlotName[EquipmentPanel.IS_TALISMAN_1751] = "普通护符3(175%)";
			mItemSlotName[EquipmentPanel.IS_TALISMAN_1752] = "普通护符4(175%)";
			mItemSlotName[EquipmentPanel.IS_TALISMAN_1251] = "普通护符5(125%)";
			mItemSlotName[EquipmentPanel.IS_TALISMAN_1252] = "普通护符6(125%)";
			mItemSlotName[EquipmentPanel.IS_TALISMAN_1001] = "普通护符7(100%)";
			mItemSlotName[EquipmentPanel.IS_TALISMAN_1002] = "普通护符8(100%)";

			mItemSlotName[EquipmentPanel.IS_CASH_TALISMAN_200] = "额外护符(200%)";
			mItemSlotName[EquipmentPanel.IS_CASH_TALISMAN_175] = "额外护符(175%)";
			mItemSlotName[EquipmentPanel.IS_CASH_TALISMAN_125] = "额外护符(125%)";
			mItemSlotName[EquipmentPanel.IS_CASH_TALISMAN_100] = "额外护符(100%)";

			mItemSlotName[EquipmentPanel.IS_CASH_GLYGH1] = "额外纹章1";
			mItemSlotName[EquipmentPanel.IS_CASH_GLYGH2] = "额外纹章2";
			mItemSlotName[EquipmentPanel.IS_CASH_GLYGH3] = "额外纹章3";
		}

		/// <summary>
		/// 获取所有套装属性
		/// </summary>
		/// <returns></returns>
		private IEnumerator<Property> AllSetsRroperties() {
			foreach (KeyValuePair<int, SetEntry> entry in mEquipedSets) {
				foreach (Property prop in entry.Value.properties) {
					if ((int)prop.tag <= GetSetItemCount(entry.Key)) {
						Property p = new Property();
						p.id = (PropertyID)((int)prop.id);
						p.value = prop.value;
						yield return p;
					}
				}
			}
		}

		/// <summary>
		/// 获取所装备指定套装的物品数量
		/// </summary>
		/// <param name="setId">套装id</param>
		public int GetSetItemCount(int setId) {
			if (mSetCounts.ContainsKey(setId))
				return mSetCounts[setId];
			return 0;
		}

		public EquipmentPanel(Character ch) {
			mCharacter = ch;
			mItemSlot = new Dictionary<int, IEquipmentProperyable>(IS_MAX_COUNT);
			mCharacter.OnCharacterClosed += mCharacter_OnCharacterClosed;
			for (int i=0; i<IS_MAX_COUNT; i++) {
				IItemSlot slot = null;
				switch (i) {
				case IS_TALISMAN_1001:
				case IS_TALISMAN_1002:
				case IS_CASH_TALISMAN_100:
					slot = new MultiplyableSlot(i, mItemSlotName[i], 1, new ItemType[] { mItemSlotType[i] });
					break;
				case IS_TALISMAN_1251:
				case IS_TALISMAN_1252:
				case IS_CASH_TALISMAN_125:
					slot = new MultiplyableSlot(i, mItemSlotName[i], 1.25f, new ItemType[] { mItemSlotType[i] });
					break;
				case IS_TALISMAN_1751:
				case IS_TALISMAN_1752:
				case IS_CASH_TALISMAN_175:
					slot = new MultiplyableSlot(i, mItemSlotName[i], 1.75f, new ItemType[] { mItemSlotType[i] });
					break;
				case IS_TALISMAN_2001:
				case IS_TALISMAN_2002:
				case IS_CASH_TALISMAN_200:
					slot = new MultiplyableSlot(i, mItemSlotName[i], 2f, new ItemType[] { mItemSlotType[i] });
					break;
				default:
					slot = new ItemSlot(i, new ItemType[] { mItemSlotType[i] }, mItemSlotName[i]);
					break;
				}

				slot.OnItemChanged += OnItemChanged;
				mItemSlot.Add(i, slot);
			}
		}

		/// <summary>
		/// 处理角色关闭事件
		/// </summary>
		void mCharacter_OnCharacterClosed(object sender, EventArgs e) {
			foreach (KeyValuePair<int, IEquipmentProperyable> entry in mItemSlot) {
				IItemSlot slot = entry.Value as IItemSlot;
				if(slot != null)
					slot.CleanupEvents();
			}
			OnPropertyChanged = null;
		}

		/// <summary>
		/// 处理物品改变事件
		/// </summary>
		private void OnItemChanged(IItemSlot slot, IUserItem oldItem) {
			RecalculateProperty();
			if (OnPropertyChanged != null) {
				OnPropertyChanged();
			}
		}

		/// <summary>
		/// 装备面板应用的属性变化事件
		/// </summary>
		public event OnEquipementChangedHandler OnPropertyChanged;

		/// <summary>
		/// 获取指定属性的装备属性加和
		/// </summary>
		public float GetProperty(PropertyID pid) {
			if (PropertyUtil.IsPercentProperty((int)pid))
				//return (float)Math.Round(mFloatProperty[(int)pid], 4);
				return mFloatProperty[(int)pid];
			else
				return mFloatProperty[(int)pid];
		}

		/// <summary>
		/// 装备物品
		/// </summary>
		/// <param name="item">要装备的物品</param>
		/// <returns>由于装备物品时而强制卸下的物品</returns>
		public IUserItem[] Equip(IUserItem item) {
			IItemSlot slotEmpty = null;
			IItemSlot slotNotEmpty = null;
			IUserItem[] oldItems = null;
			foreach (IEquipmentProperyable equip in mItemSlot.Values) {
				IItemSlot slot = equip as IItemSlot;
				if (slot!= null && slot.CanEquip(item)) {
					if (slot.Item == null) {
						slotEmpty = slot;
						break;
					} else if(slotNotEmpty == null){
						slotNotEmpty = slot;
					}
				}
			}
			if (slotEmpty != null) {
				oldItems = slotEmpty.Equip(item);
			} else if (slotNotEmpty != null) {
				oldItems = slotNotEmpty.Equip(item);
			}
			return oldItems;
		}

		/// <summary>
		/// 测试是否可以装备指定物品
		/// </summary>
		public bool CanEquip(IUserItem item) {
			foreach (IEquipmentProperyable equip in mItemSlot.Values) {
				IItemSlot slot = equip as IItemSlot;
				if (slot!= null && slot.CanEquip(item)) {
					return true;
				}
			}
			return false;
		}

		/// <summary>
		/// 卸下指定物品槽的物品
		/// </summary>
		public IUserItem Uneuip(int slotId) {
			IItemSlot slot = GetSlot<IItemSlot>(slotId);
			if (slot != null && slot.Item != null) {
				return slot.Unequip();
			}
			return null;
		}

		public T GetSlot<T>(int slotId) where T:class{
			if(slotId>=0 && slotId<mItemSlot.Count)
				return mItemSlot[slotId] as T;
			return null;
		}

		/// <summary>
		/// 索引或是设置物品槽
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public IEquipmentProperyable this[int id] {
			get { 
				if(mItemSlot.ContainsKey(id))
					return mItemSlot[id];
				return null;
			}
			set {
				if (mItemSlot.ContainsKey(id))
					mItemSlot[id] = value;
				else
					mItemSlot.Add(id, value);
				RecalculateProperty();
				if (OnPropertyChanged != null) {
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// 重新计算属性值到缓存
		/// </summary>
		void RecalculateProperty() {
			for (int i=0; i<mFloatProperty.Length; i++)
				mFloatProperty[i] = 0;
			mSetCounts.Clear();
			mEquipedSets.Clear();
			foreach (IEquipmentProperyable equip in mItemSlot.Values) {
				IItemSlot slot = equip as IItemSlot;
				if (slot != null && slot.Item != null && slot.Item.setId>0) {
					mEquipedSets[slot.Item.setId] = slot.Item.set;
					if(!mSetCounts.ContainsKey(slot.Item.setId)){
						mSetCounts[slot.Item.setId] = 0;
					}
					mSetCounts[slot.Item.setId]++;
				}
			}

			int p, p1, p2;
			foreach (IEquipmentProperyable slot in mItemSlot.Values) {
				foreach (Property prop in slot) {
					p = PropertyUtil.GetPropertyOneMapTwo(((int)prop.id), out p1, out p2);
					if (PropertyUtil.IsPercentProperty((int)prop.id)) {
						if (p1>=0) {
							mFloatProperty[p1] += prop.value;
							mFloatProperty[p2] += prop.value;
						}else
							mFloatProperty[(int)prop.id] += prop.value;
					} else {
						if (p1>=0) {
							mFloatProperty[p1] += prop.value;
							mFloatProperty[p2] += prop.value;
						} else
							mFloatProperty[(int)prop.id] += prop.value;
					}
				}
			}

			IEnumerator<Property> setProps = AllSetsRroperties();
			while (setProps.MoveNext()) {
				Property prop = setProps.Current;
				p = PropertyUtil.GetPropertyOneMapTwo(((int)prop.id), out p1, out p2);
				if (PropertyUtil.IsPercentProperty((int)prop.id)) {
					if (p1>=0) {
						mFloatProperty[p1] += prop.value;
						mFloatProperty[p2] += prop.value;
					} else
						mFloatProperty[(int)prop.id] += prop.value;
				} else {
					if (p1>=0) {
						mFloatProperty[p1] += prop.value;
						mFloatProperty[p2] += prop.value;
					} else
						mFloatProperty[(int)prop.id] += prop.value;
				}
			}
		}

		public delegate void OnEquipementChangedHandler();
	}

	/// <summary>
	/// 物品槽接口
	/// </summary>
	public interface IItemSlot : IEquipmentProperyable {

		event ItemSlotItemChangedHandlder OnItemChanged;

		object Tag { get; set; }

		IUserItem Item { get; }

		bool CanEquip(IUserItem item);

		IUserItem Unequip();

		IUserItem[] Equip(IUserItem item);


		void CleanupEvents();
	}

	/// <summary>
	/// 物品槽物品改变的消息，当oldItem与当前的Item引用相同时，理解为Item内部属性可能发生了变化
	/// </summary>
	/// <param name="slot"></param>
	/// <param name="oldItem"></param>
	public delegate void ItemSlotItemChangedHandlder(IItemSlot slot, IUserItem oldItem);

	/// <summary>
	/// 应用效果加倍物品槽
	/// </summary>
	public class MultiplyableSlot : ItemSlot {
		private float mMultiply;
		public MultiplyableSlot(int slotId, string slotName, float multiply, ItemType[] itemTypes)
			: base(slotId, itemTypes, slotName) {
				mMultiply = multiply;
		}

		public float Multiply {
			get { return mMultiply; }
		}

		public override IEnumerator<Property> GetEnumerator() {
			if (Item != null) {
				foreach (Property prop in Item) {
					Property p = new Property();
					p.value = prop.value*mMultiply;
					p.tag = prop.tag;
					p.id = prop.id;
					yield return p;
				}
			}
		}

		public override string ToString() {
			if (Item != null)
				return Item.name+"(+"+(mMultiply-1)+"%)";
			return "Slot:"+Id+"(+"+(mMultiply-1)+"%)";
		}

	}

	/// <summary>
	/// 一般物品槽
	/// </summary>
	public class ItemSlot : IItemSlot{

		public event ItemSlotItemChangedHandlder OnItemChanged;

		private IUserItem mItem;
		private int mSlotId;
		private ItemType[] mEquipItemTypes;
		private string mSlotName;

		public ItemSlot(int slotId, ItemType[] itemTypes, string slotName) {
			mSlotId = slotId;
			mEquipItemTypes = itemTypes;
			mSlotName = slotName;
		}

		public object Tag { get; set; }

		public int Id {
			get { return mSlotId; }
		}

		/// <summary>
		/// 获取或是直接设置装备的武器
		/// </summary>
		public IUserItem Item {
			get { return mItem; }
			set {
				IUserItem old = mItem;
				mItem = value;
				if (OnItemChanged!=null) {
					OnItemChanged(this, old);
				}
			}
		}

		public virtual bool CanEquip(IUserItem item) {
			for (int i=0; i<ItemTypes.Length; i++) {
				if (ItemTypes[i] == item.exchangType)
					return true;
			}
			return false;
		}

		public virtual IUserItem Unequip() {
			IUserItem oldItem = Item;
			Item = null;
			return oldItem;
		}

		public virtual IUserItem[] Equip(IUserItem item) {
			IUserItem oldItem = Item;
			if (CanEquip(item)) {
				Item = item;
			}
			if (oldItem != null) {
				return new IUserItem[] { oldItem };
			}
			return new IUserItem[] { };
		}

		protected virtual ItemType[] ItemTypes {
			get { return mEquipItemTypes; }
		}

		

		public override string ToString() {
			if(Item != null)
				return Item.name;
			return "Slot:"+mSlotId;
		}

		public virtual IEnumerator<Property> GetEnumerator() {
			if(Item != null)
				return Item.GetEnumerator();
			return EmptyEnumerator();
		}

		protected IEnumerator<Property> EmptyEnumerator() {
			yield break;
		}


		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
			return GetEnumerator();
		}

		public string SlotName {
			get { return mSlotName; }
		}



		public void CleanupEvents() {
			OnItemChanged = null;
		}
	}

	/// <summary>
	/// 英雄等级效果装备槽
	/// </summary>
	public class HerolProperty : IEquipmentProperyable {

		/// <summary>
		/// 英雄等级属性
		/// </summary>
		private List<Property> mHeroPropertyList;
		private int mLevel;

		public HerolProperty(int level) {
			mLevel = level;
			mHeroPropertyList = new List<Property>();
			if (mLevel > 0) {
				DnResourceUtil.GetFirstPotencialProperties((int)DnResourceUtil.HeroLevelTable[mLevel-1, 1], mHeroPropertyList);
			}
		}

		public int Id {
			get { return Character.HeroPropertyID; }
		}

		/// <summary>
		/// 英雄等级
		/// </summary>
		public int Level {
			get { return mLevel; }
		}

		public IEnumerator<Property> GetEnumerator() {
			return mHeroPropertyList.GetEnumerator();
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
			return GetEnumerator();
		}


		public string SlotName {
			get { return "英雄等级效果"; }
		}
	}

	/// <summary>
	/// 称号装备槽
	/// </summary>
	public class Appellation : IEquipmentProperyable {

		private int mAppellationId;

		/// <summary>
		/// 装备槽id
		/// </summary>
		public int Id {
			get { return Character.AppellationID; }
		}

		/// <summary>
		/// 等级限制
		/// </summary>
		public int LevelLimit {
			get { return (int)DnResourceUtil.Appellationtable[AppellationId, 1]; }
		}

		/// <summary>
		/// 称号名称
		/// </summary>
		public string Name {
			get {
				string s = Util.FindUIString((int)DnResourceUtil.Appellationtable[AppellationId, 0]);
				if (s == null) {
					s = "";
				}
				return s;
			}
		}

		public override string ToString() {
			return "称号："+Name;
		}

		/// <summary>
		/// 称号描述
		/// </summary>
		public string Description {
			get {
				string s = Util.FindUIString((int)DnResourceUtil.Appellationtable[AppellationId, 2]);
				if (s == null) {
					s = "";
				}
				return s;
			}
		}

		/// <summary>
		/// 称号id
		/// </summary>
		public int AppellationId {
			get { return mAppellationId; }
			set {
				mAppellationId = value;
			}
		}

		public IEnumerator<Property> GetEnumerator() {
			Dntable table = DnResourceUtil.Appellationtable;
			for (int i=3; i<21; i+=2) {
				if ((int)table[AppellationId, i] >= 0) {
					if (Util.StateVlauePettern.IsMatch((string)table[AppellationId, i+1])) {
						Property prop = new Property();
						prop.id = (PropertyID)(int)table[AppellationId, i];
						prop.value = float.Parse((string)table[AppellationId, i+1]);
						if (prop.value == 0)
							continue;
						yield return prop;
					}
				}
			}
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
			return GetEnumerator();
		}

		public string SlotName {
			get { return "称号效果"; }
		}
	}

	/// <summary>
	/// 装备槽接口
	/// </summary>
	public interface IEquipmentProperyable : IEnumerable<Property> {
		int Id { get; }

		string SlotName { get; }
	}

	/*
		 * 38	强化纹章
		 * 5	金属板
		 * 8	金属板袋子，宝石口袋（ HD），阿切尔辅助武器口袋[随机物品]
		 * 105	祝福之石，强者之石，巨龙增益，小龙妹证物，贵族的祝福
		 * 123	意志碎片，阿尔泰亚女神之石，令人愉快的专属优惠
		 * 6	恢复碎片，鸡腿(HP +30%)
		 * 132	护符
		 * 2	绚烂攻击神药，体力枯竭之药水（HP -30%），绚烂致命一击神药，
		 * 187	幸运币 - 天梯赛，幸运币 - 噩梦之星
		 * 65	应急攻击神药（小），
		 * 4	红宝石碎片，最高级石榴石，大地宝石，超级宝玉,[宝玉]
		 * 2	八角结晶，龙泪，普通的次级星光
		 * 152	次级大地宝石，高级阿尔塔金属碎片，战场的 纪念币（3000金币），战场的自然原石，地狱犬的肋排，天启的地狱暗红，[制作材料]
		 * 0	道林的长剑，柏林的短弓
		 * 1	新手学者制服，新手舞娘紧身胸衣，新手兽娘披风，魔法师 基本 发型01，兽娘 基本脸型01，鲜花的戒指
		 * 2	地狱犬的耳朵，狮蝎的肩膀，深色的龙玉心脏，[制作材料][礼物][交换道具]
		 * 2	高级夜影的强化龙玉
		 * 126	记忆碎片
		 * 97	闪电的马牌
		 * 84	称号
		 * 167	经验值胶囊
		 * 160	勇士的武器口袋（主武器1）[指定职业口袋]
		 * 46	5与伦比的魅力锤子袋子
		 * 112	勇士的饰品口袋
		 * 43	中级水晶代码
		 * 101	称号：捐款天使交换券
		 * 14	冒险家专用背包
		 * 15	仓库收纳箱
		 * 29	忘却之契约（基础+1转+2转）
		 * 32	花冠
		 * 33	VIP
		 * 39	混合箱子
		 * 47	巢穴额外入场券
		 * 40	改变口音的麦克风
		 * 49	300龙币商品券，5000龙币商品券
		 */

	/*
	 * 29	精灵

普通装备			0	0	0
主武器			1	0	1
辅助武器			1	0	2
头盔				1	0	3
上装				1	0	4
下装				1	0	5
手套				1	0	6
鞋				1	0	7
项链				1	1	8
耳环				1	1	9
戒指				1	1	10
药水/卷轴			1	6	11
宝玉				1	6	12

其他				1	6	15
主武器			1	7	16
辅助武器			1	7	17
头盔				1	7	18
上装				1	7	19
下装				1	7	20
手套				1	7	21
鞋				1	7	22
项链				1	8	23
耳环				1	8	24
戒指				1	8	25
翅膀				1	8	26
尾巴				1	8	27
印花						28
精灵						29
药水/卷轴			1	9	30
强化				1	9	31
其他				1	9	32
强化纹章			1	2	33
技能纹章			1	2	34
特殊技能纹章		1	2	35
武器防具代码				36
饰品代码					37
消亡方块					38
料理食谱			1	11	39
料理				1	11	40
种子				1	11	41
农产品			1	11	42
水产				1	11	43
活动道具？				44
技能书					45
随机物品，口袋				46
坐骑，宠物及其饰品等		47
更改外形			1	9	48
龙币商品券		1	9	49
强化代码及其交换券			50
根源				1	6	51
强化护符			1	4	52
强化龙玉			1	3	54
技能龙玉			1	3	55
金属板					56
祝福护符					57
富饶护符					58
	 *				59	先祖钥匙，次元之箱钥匙，王城宝箱钥匙，次元水晶碎片
	 *				60	女神的眼泪，女神的意志，女神的怜悯。。，噩梦之星，卷轴碎片，女神光彩
	 *				61	女神的奖牌，女神的勋章
	 *				62	绚烂交换券
	 *				63	冒险家公会会长的银币，战场胜负师的金币，赠品交换券，辞旧迎新套装交换券
交换券			1	6	64
封印印章			1	6	65
装备制作材料		1	5	66
龙玉制作材料		1	5	67
护符制作材料		1	5	68
技巧饰品制作材料	1	5	69
					70 粉末，确认，词缀材料等
称号						71
礼物						72
经验值胶囊				73
佣兵				1	6	74
怪物卡			1	6	75
刻印				1	6	76





	 */
}
